import React from 'react'
import { Button, Row, Icon, Input, Progress, Spin, Table, Tag, Tooltip, Divider } from 'antd'
import { FormattedMessage } from 'react-intl'
import Highlighter from 'react-highlight-words'
import _ from 'lodash'
import { convertContent } from '../../../../../constant/lang-util'
import RefreshTool from '../../../../common/refresh-tool'
import { getProgramOverview } from '../../../../../actions/program'
import { withRouter } from 'react-router-dom'
import { connect } from 'react-redux'
import { getAssignmentQuizTagsByProgramId } from '../../../../../actions/assignment-quiz-tag'

class ProgramOverviewBody extends React.Component {
  state = {
    spinning: true,
    searchText: '',
    programOverview: []
  }
  componentDidMount = () => {
    const {user} = this.props
    const {programId} = this.props.match.params
    this.props.getAllAssignmentQuizTagsByProgramId(programId)
    if (user.id > 0) {
      this.props.getProgramOverview(programId, user.id, `训练营总览`, (programOverview) => {
        this.setState({spinning: false, programOverview:programOverview.data})
      })
    }
  }

  componentWillReceiveProps = nextProps => {
    const {user} = nextProps
    if (this.props.user === user) {
      return false
    }
    const {programId} = this.props.match.params
    this.props.getProgramOverview(programId, user.id, `训练营总览`, (programOverview) => {
      this.setState({spinning: false, programOverview:programOverview.data})
    })
  }
  refreshProgramOverview = () => {
    const {user} = this.props
    const {programId} = this.props.match.params
    this.setState({spinning: true})
    this.props.getProgramOverview(programId, user.id, `训练营总览`, (programOverview) => {
      this.setState({spinning: false, programOverview:programOverview.data})
    },false)
  }

  getColumnSearchProps = dataIndex => ({
    filterDropdown: ({setSelectedKeys, selectedKeys, confirm, clearFilters}) => (
      <div style={{padding: 8}}>
        <Input
          ref={node => {
            this.searchInput = node
          }}
          placeholder={`Search ${dataIndex}`}
          value={selectedKeys[0]}
          onChange={e => setSelectedKeys(e.target.value ? [e.target.value] : [])}
          onPressEnter={() => this.handleSearch(selectedKeys, confirm)}
          style={{width: 188, marginBottom: 8, display: 'block'}}
        />
        <Button
          type="primary"
          onClick={() => this.handleSearch(selectedKeys, confirm)}
          icon="search"
          size="small"
          style={{width: 90, marginRight: 8}}
        >
          Search
        </Button>
        <Button onClick={() => this.handleReset(clearFilters)} size="small" style={{width: 90}}>
          Reset
        </Button>
      </div>
    ),
    filterIcon: filtered => (
      <Icon type="search" style={{color: '#1890ff'}}/>
    ),
    onFilter: (value, record) =>
      (record[dataIndex] || '')
        .toString()
        .toLowerCase()
        .includes(value.toLowerCase()),
    onFilterDropdownVisibleChange: visible => {
      if (visible) {
        setTimeout(() => this.searchInput.select())
      }
    },
    render: text => (
      <Highlighter
        highlightStyle={{backgroundColor: '#ffc069', padding: 0}}
        searchWords={[this.state.searchText]}
        autoEscape
        textToHighlight={text.toString()}
      />
    ),
  })

  handleSearch = (selectedKeys, confirm) => {
    confirm()
    this.setState({searchText: selectedKeys[0]})
  }

  handleReset = clearFilters => {
    clearFilters()
    this.setState({searchText: ''})
  }

  getColumns = data => {
    const taskAssignment = {}
    const colomns = [{
      title: <FormattedMessage id='排名'/>,
      dataIndex: 'rankScore',
      width: 50,
      key: 'rankScore',
      fixed: 'left',
      render: (text, record, index) => {
        return <span>{index + 1}</span>
      }
    }, {
      title: <FormattedMessage id='等级'/>,
      dataIndex: 'level',
      width: 100,
      key: 'level',
      fixed: 'left'
    }, {
      title: <FormattedMessage id='姓名'/>,
      dataIndex: 'name',
      width: 100,
      key: 'name',
      fixed: 'left'
    }, {
      title: 'Tag',
      dataIndex: 'tag',
      width: 100,
      fixed: 'left',
      ...this.getColumnSearchProps('tag'),
      sorter: (a, b) => a - b < 0,
      render: (item) => {
        return <span>{this.formatTags(item)}</span>
      }
    }, {
      title: <FormattedMessage id={'总完成度/质量统计'}/>,
      width: 200,
      render: (text, record) => {
        return <div><p>
          <Tooltip title={convertContent('完成度')}>
            <Progress
              style={{width: 150}}
              size="small"
              format={() => `${record.assignments.filter(item => (item.grade || 0) > 60).length} / ${record.assignments.length || 0}`}
              percent={this.statisticFinishRate(record.assignments)}/>
          </Tooltip>
        </p>
          {this.statisticQuality(record.assignments)}
        </div>
      }
    }]
    data.forEach(item => {
      if (!taskAssignment[item['topicTitle']]) {
        taskAssignment[item['topicTitle']] = new Set()
      }
      taskAssignment[item['topicTitle']].add(item['taskTitle'])
    })
    Object.keys(taskAssignment).forEach(task => {
      const taskAssignments = Array.from(taskAssignment[task])
      if (taskAssignment[task]) {
        const assignmentColumns = taskAssignments.map((task, index) => ({
          title: task, width: 200, dataIndex: task, key: task + index,
          render: (item) => {
            return <div>
              <p>
                <Tooltip title={convertContent('完成度')}>
                  <Progress
                    style={{width: 150}}
                    key={index}
                    size="small"
                    format={() => `${item.filter(item => (item.grade || 0) > 60).length} / ${item.length || 0}`}
                    percent={this.statisticFinishRate(item)}/>
                </Tooltip>
              </p>
              {this.statisticQuality(item)}
            </div>
          }
        }))
        colomns.push({
          title: task,
          children: assignmentColumns
        })
      }
    })

    return colomns
  }

  statisticQuality = assignments => {
    const {assignmentQuizTags} = this.props
    const total = assignments.length || 1
    return <span>
      {assignmentQuizTags.map((tag, index) => {
        return <span key={index}>
          <Tag color={tag.color}>{tag.name}</Tag> :
          {(assignments.filter(assignment => (assignment.assignmentTag || '')
            .includes(tag.name)).length * 100 / total).toFixed(2)} %
          <br/>
        </span>
      })}
    </span>
  }

  statisticFinishRate = assignments => {
    return (assignments.filter(item => (item.grade || 0) > 60).length / (assignments.length || 1) * 100).toFixed(0)
  }
  formatTags = (item) => {
    if (!item) return ''
    const tagColors = item.split(',')
    return tagColors.map((item, index) => {
      const tagColor = item.split('|')
      return <Tag color={tagColor[1]} key={index}>{tagColor[0]}</Tag>
    })
  }

  statisticRankScore = assignments => {
    const get = assignment => {
      const tag = (assignment.assignmentTag || '').split('|')[0]
      switch (tag) {
        case 'Outstanding':
          return 9.5
        case 'Good':
          return 8.5
        case 'Competent':
          return 7
        case 'Developing':
          return 5.5
        case 'Marginal':
          return 5
        default :
          return 0
      }
    }
    return assignments.reduce((sum, assignment) => {
      sum += get(assignment)
      return sum
    }, 0)
  }
  statisticLevel = averageScore => {
    if (averageScore >= 9) return 'Outstanding'
    if (averageScore >= 8) return 'Good'
    if (averageScore >= 6) return 'Competent'
    if (averageScore >= 5) return 'Developing'
    return 'Marginal'
  }

  formatData = programOverview => {
    let formatData = []

    const grouped = _.groupBy(programOverview, item => item['name'])
    Object.keys(grouped).forEach(name => {
      const assignments = grouped[name]
      const rankScore = this.statisticRankScore(assignments)
      const level = this.statisticLevel(rankScore / assignments.length)

      let student = {
        name, tag: grouped[name][0].tag, assignments: [],
        rankScore, level
      }
      assignments.forEach(assignment => {
        if (student[assignment['taskTitle']]) {
          student[assignment['taskTitle']].push(assignment)
        } else {
          student[assignment['taskTitle']] = [assignment]
        }
        student.assignments.push(assignment)
      })
      formatData.push(student)
    })
    formatData.sort((a, b) => b.rankScore - a.rankScore)
    return formatData
  }

  render () {
    const {spinning} = this.state
    const {programOverview} = this.props
    const columns = this.getColumns(programOverview.data)
    const studentData = this.formatData(programOverview.data)

    return <Spin size="large" spinning={spinning} tip='loading'>
      <Row type='flex' justify='end'>
        <RefreshTool
          refresh={this.refreshProgramOverview}
          refreshTime={programOverview.refreshTime}
        />
      </Row>
      <Divider/>
      <Table
        columns={columns}
        dataSource={studentData}
        bordered
        rowKey={item => item.name}
        pagination={false}
        size='small'
        scroll={{x: 'max-content'}}
      />
    </Spin>
  }
}

const mapStateToProps = ({programOverview, user, assignmentQuizTags}) => ({
  programOverview, user, assignmentQuizTags
})
const mapDispatchToProps = dispatch => ({
  getProgramOverview: (programId, tutorId, type, callback,fromCache) => dispatch(getProgramOverview(programId, tutorId, type, callback,fromCache)),
  getAllAssignmentQuizTagsByProgramId: (programId) => dispatch(getAssignmentQuizTagsByProgramId(programId)),
})

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(ProgramOverviewBody))
